﻿using System;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Text;

namespace Bettzueche_CCR.Benchmarks {
    static class Utilities {

        /// <summary>
        /// Schreibt in die angegebene Datei die spezifiezierten Informationen sowie einige MaschinenInfos
        /// als CSV (Semikolon als Trennzeichen).
        /// </summary>
        /// <param name="logFile">Name(Pfad) der LogDatei</param>
        /// <param name="repititions">Anzahl der ausgeführten Schleifendurchläufe</param>
        /// <param name="startTime">Startzeit des Tests</param>
        /// <param name="mSeconds">Ausführungsdauer des Tests in Millisekunden</param>
        /// <param name="header">Überschrift, der den Test beschreibt</param>
        internal static void WriteLog(string logFile, int repititions, DateTime startTime, double mSeconds, string header) {
            NumberFormatInfo info = new NumberFormatInfo();
            info.NumberDecimalSeparator = ",";
            info.NumberGroupSeparator = ".";
            info.NumberGroupSizes = new int[] { 3 };
            info.NumberDecimalDigits = 0;

            FileStream fs = new FileStream(logFile, FileMode.Append);
            TextWriter writer = new StreamWriter(fs);

            try {
                writer.WriteLine(header + ";# Schleifen;Startzeit;Dauer (ms);Betriebssystem;# Kerne;Prozessspeicher (kB);# alle Prozesse;CLR Version");
                StringBuilder text = new StringBuilder();
                String seperator = ";";

                text.Append(seperator);
                text.Append(repititions.ToString("N", info)).Append(seperator);
                text.Append(startTime).Append(seperator);
                text.Append(mSeconds).Append(seperator);
                OperatingSystem os = Environment.OSVersion;
                text.Append(os).Append(seperator);
                text.Append(Environment.ProcessorCount).Append(seperator);
                string kBytes = (Environment.WorkingSet >> 10).ToString("N", CultureInfo.CurrentCulture);
                text.Append(kBytes).Append(seperator);
                text.Append(Process.GetProcesses().Length).Append(seperator);
                text.Append(Environment.Version);
                writer.WriteLine(text.ToString());
                writer.WriteLine();
            }
            catch (Exception ex) {
                Console.WriteLine("Error while writing Log:\n" + ex);
            }
            finally {
                writer.Close();
                fs.Close();
            }
        }
    }

    /// <summary>
    /// Abstract Benchmark class, provides Start-/EndTime, Repitions, Logfile etc.
    /// </summary>
    abstract class CallBackTester {

        /// <summary>Startzeit der Routine</summary>
        protected DateTime _startTime;
        /// <summary>Endzeit der Routine</summary>
        protected DateTime _endTime;
        /// <summary>Indicates, if computation is in progress</summary>
        protected bool computing;

        /// <summary>Gibt Anzahl Schleifendurchläufe, die eine lange Berechnung simulieren</summary>
        public int Repititions { get; protected set; }

        /// <summary>Gibt oder setzt den Pfad zur Logdatei</summary>
        public string LogFile { get; set; }

        /// <summary>
        /// print rotating cursor while local variable computing is true.
        /// </summary>
        protected void doSomeStuff() {
            string[] signs = new string[] { "|", "/", "-", "\\" };
            Console.Write(" ");
            int j = 0;
            while (computing) {
                //doing some other stuff
                Console.CursorLeft = 0;
                Console.Write(signs[j % 4]);
                j++;
                Thread.Sleep(100);
            }
            Console.CursorLeft = 0;
        }

    }
}
